#include "workthread.h"
#include <QHostAddress>
#include "client_manager.h"
#include "message.h"
#include "udpsocket.h"
#include <QTimer>

WorkThread::WorkThread(const QHostAddress &addr, quint16 port)
    :m_serverAddr(addr),
    m_port(port)
{
//  m_udp = new QUdpSocket();
  qDebug() << "WorkThread() 线程ID =" << QThread::currentThreadId();
}

void WorkThread::run() {

    qDebug() << "run 线程ID= " << QThread::currentThreadId();
    // 在run线程中创建的
    m_udp = new QUdpSocket();

    // 绑定指定IP与端口
    bool   rel = m_udp->bind(m_serverAddr,m_port, QUdpSocket::ShareAddress);
    if(rel)
    {
       emit showMessage("绑定成功，等待接收UDP数据");
    }else {
       emit showMessage("绑定失败" + m_udp->errorString());
    }

  // 接收到数据的信号,因为m_udp是子线程对象，采用QT::DirectConnection，槽会在发送者的线程中执行，即在子线程中执行。
  connect(m_udp, SIGNAL(readyRead()), this, SLOT(onReadyRead()),
          Qt::DirectConnection);

  //如果不用这样的表达式，就得重写QUdpServer
  auto sendData = [=](const QString &data) {
    qDebug() << "发送数据数据的线程ID= " << QThread::currentThreadId();
    ClientManager::getInstance().sendData(*m_udp,data);
  };

  // 这里this是主线程的对象，m_udp是子线程的对象
  connect(this, &WorkThread::doSend, m_udp, sendData,
          Qt::QueuedConnection);

  // 启动事件循环,否则信号槽不生效
  exec();

  // 销毁对象
  m_udp->deleteLater();
  qDebug() << "线程结束了!";
}

void WorkThread::stopThread() {
  // 应该调用quit或者exit来退出事件循环
  exit(0);
}

void WorkThread::onDisconnected() {
  emit showMessage("连接被断开！");
  exit(0); // 退出循环
  emit onThreadStoped(this);
}

void WorkThread::onReadyRead() {
  qDebug() << "接收数据的线程ID= " << QThread::currentThreadId();
  //是否有数据抵达
  while ( m_udp->hasPendingDatagrams())
  {
      //获取要读取数据的大小
      int size = m_udp->pendingDatagramSize();

      //定义一块缓冲区，来接收数据
      QByteArray arr;
      arr.resize(size);

      QHostAddress  addr; //发送方的IP
      quint16  port;//发送方的端口

      //接收数据的同时，获取到对方的IP与端口
      int rel = m_udp->readDatagram(arr.data(),size, &addr,&port);

      if(rel > 0)
      {
          QHostAddress  ipv4 (addr.toIPv4Address());
          //保存客户端的IP与端口，方便群发数据给客户端
          //重复则插入不进去
          ClientManager::getInstance().addClient(ipv4 ,port) ;

          Message message(arr);
          QString str = "";
          if(!message.isHeartMessage()){
              str = QString("接收到%1:%2的消息: %3")
                        .arg(ipv4.toString()).arg(port).arg(message.getMessage());

          }else{
              int count =  ClientManager::getInstance().heart(ipv4 ,port) ;
              str = QString("%1:%2心跳次数: %3")
                        .arg(ipv4.toString()).arg(port).arg(count);
          }

          emit  showMessage(str);

      }

  }
}
void  WorkThread::sendData(const QString &data){
   qDebug() << "发数据 " << QThread::currentThreadId();
  //m_udp->write(data.toUtf8());
   emit doSend(data);
}
